//
//  ChartCanvas.m
//  ChartRefactor
//
//  Created by CaoJun on 15/3/9.
//  Copyright (c) 2015年 CaoJun. All rights reserved.
//

#import "ChartCanvas.h"
#import <CoreText/CoreText.h>

@implementation ChartCanvas


-(void) save
{
    CGContextSaveGState(self.context);
}

-(void) restore
{
    CGContextRestoreGState(self.context);
}

-(void) setLineWidth:(CGFloat) width
{
    CGContextSetLineWidth(self.context, width);
}

-(void) setLineCap:(CGLineCap) cap
{
    CGContextSetLineCap(self.context, cap);
}
-(void) setLineJoin:(CGLineJoin) join
{
    CGContextSetLineJoin(self.context, join);
}

-(void) setFillStyle:(NSString *) color
{
    UIColor * uicolor = [ChartCanvas colorWithHexString: color];

    CGContextSetFillColorWithColor(self.context, uicolor.CGColor);
}

-(void) setFillColor:(UIColor *) color
{
    CGContextSetFillColorWithColor(self.context, color.CGColor);
}

-(void) setStrokeStyle:(NSString *) color
{
    UIColor * uicolor = [ChartCanvas colorWithHexString: color];

    CGContextSetStrokeColorWithColor(self.context, uicolor.CGColor);
}

- (void)setStrokeColor:(UIColor *)color
{
    CGContextSetStrokeColorWithColor(self.context, color.CGColor);
}

-(void) drawLineWithX1:(CGFloat) x1 withY1:(CGFloat) y1 withX2:(CGFloat) x2 withY2:(CGFloat) y2
{
    CGContextBeginPath(self.context);
    //起始点设置为(0,0):注意这是上下文对应区域中的相对坐标，
    CGContextMoveToPoint(self.context, x1, y1);
    //设置下一个坐标点
    CGContextAddLineToPoint(self.context, x2, y2);
    //连接上面定义的坐标点
    CGContextStrokePath(self.context);

//    Stroking the path resets the context's current path to empty, so there is no currentpoint after you call CGContextStrokePath().
//
//    ClosePath() isn't there to balance BeginPath() — it modifies the current path by adding a line segment from the current point to the beginning of the current subpath (in such a way that there's a linejoin at that point rather than a pair of line ends). A PostScript tutorial might have a clearer explanation of these operators.
//
//    Although, in this case you'd want to be careful about the difference between PostScript and PDF.  If I remember correctly, the PostScript fill and stroke operators do NOT consume the current path while in PDF (on which Quartz 2D is based) they do consume the current path.

//    CGContextClosePath(self.context);
}

-(void) drawLineWithLineWidth:(CGFloat) lineWidth WidthLineColor:(NSString *) lineColor  withX1:(CGFloat) x1 withY1:(CGFloat) y1 withX2:(CGFloat) x2 withY2:(CGFloat) y2
{
    [self setStrokeStyle:lineColor];
    [self setLineWidth:lineWidth];
    [self drawLineWithX1:x1 withY1:y1 withX2:x2 withY2:y2];
}

-(void) drawLines:(NSArray * )points
{
    CGContextBeginPath(self.context);
    NSValue *val = points[0];
    CGPoint p0 = [val CGPointValue];
    CGContextMoveToPoint(self.context, p0.x, p0.y);
    for (id item in points) {
        CGPoint point = [item CGPointValue];
        CGContextAddLineToPoint(self.context, point.x, point.y);
    }
    CGContextStrokePath(self.context);

//    CGContextClosePath(self.context);
}

-(void) drawLinesWithLineWidth:(CGFloat) lineWidth WidthLineColor:(NSString *) lineColor withPoints:(NSArray * )points
{
    [self setStrokeStyle:lineColor];
    [self setLineWidth:lineWidth];
    [self drawLines:points];
}

-(void) drawDashedWithLength:(CGFloat[]) lengths withSize:(size_t) size withX1:(CGFloat) x1 withY1:(CGFloat) y1 withX2:(CGFloat) x2 withY2:(CGFloat) y2
{
    CGContextSaveGState(self.context);

    CGContextSetLineDash(self.context, 0, lengths, size);

    [self drawLineWithX1:x1 withY1:y1 withX2:x2 withY2:y2];

    CGContextRestoreGState(self.context);
}

- (void)drawDashLineWidth:(CGFloat)width color:(NSString *)color x1:(CGFloat)x1 y1:(CGFloat)y1 x2:(CGFloat)x2 y2:(CGFloat)y2
{
    CGContextSaveGState(self.context);
    
    const CGFloat lengths[] = {2.5, 0.5};
    const size_t size = sizeof(lengths) / sizeof(lengths[0]);
    CGContextSetLineDash(self.context, 0, lengths, size);
    [self drawLineWithLineWidth:width WidthLineColor:color withX1:x1 withY1:y1 withX2:x2 withY2:y2];
    
    CGContextRestoreGState(self.context);
}

-(void) storkeRectWithX:(CGFloat) x withY:(CGFloat) y withWidth:(CGFloat) width withHeight:(CGFloat) height
{
    [self storkeRect:CGRectMake(x, y, width, height)];
}

-(void) storkeRect:(CGRect) rect;
{
    CGContextStrokeRect(self.context, rect);
}
-(void) storkeRectWithX:(CGFloat) x withY:(CGFloat) y withWidth:(CGFloat) width withHeight:(CGFloat) height withStrokeColor: (NSString *) color
{
    [self setStrokeStyle:color];
    [self storkeRect:CGRectMake(x, y, width, height)];
}
-(void) storkeRect:(CGRect) rect withStrokeColor: (NSString *) color
{
    [self setStrokeStyle:color];
    [self storkeRect:rect];
}

-(void) fillRectWithX:(CGFloat) x withY:(CGFloat) y withWidth:(CGFloat) width withHeight:(CGFloat) height
{
    [self fillRect:CGRectMake(x, y, width, height)];
}
-(void) fillRect:(CGRect) rect
{
    CGContextFillRect(self.context, rect);
}
-(void) fillRectWithX:(CGFloat) x withY:(CGFloat) y withWidth:(CGFloat) width withHeight:(CGFloat) height withFillColor:(NSString *) color
{
    [self setFillStyle:color];
    [self fillRectWithX:x withY:y withWidth:width withHeight:height];
}
-(void) fillRect:(CGRect) rect withFillColor:(NSString *) color
{
    [self setFillStyle:color];
    [self fillRect:rect];
}

-(void) fillRectWithX1:(CGFloat) x1 withY1:(CGFloat) y1 withX2:(CGFloat) x2 withY2:(CGFloat) y2
{
    CGContextBeginPath(self.context);
    CGContextMoveToPoint(self.context, x1, y1);
    CGContextAddLineToPoint(self.context, x1, y2);
    CGContextAddLineToPoint(self.context, x2, y2);
    CGContextAddLineToPoint(self.context, x2, y1);
    CGContextAddLineToPoint(self.context, x1, y1);
    CGContextFillPath(self.context);
}
-(void) fillRectWithX1:(CGFloat) x1 withY1:(CGFloat) y1 withX2:(CGFloat) x2 withY2:(CGFloat) y2 withFillColor:(NSString *) color
{
    [self setFillStyle:color];
    [self fillRectWithX1:x1 withY1:(CGFloat) y1 withX2: x2 withY2: y2];
}

-(void) fillPath:(NSArray * )points
{
    CGContextBeginPath(self.context);
    
    NSValue *val = points[0];
    CGPoint p0 = [val CGPointValue];
    CGContextMoveToPoint(self.context, p0.x, p0.y);
    for (NSUInteger i=1,len=[points count];i<len;i++) {
        CGPoint point = [points[i] CGPointValue];
        CGContextAddLineToPoint(self.context, point.x, point.y);
    }
    
    CGContextFillPath(self.context);
}
-(void) fillPath:(NSArray * )points withFillColor:(NSString *) color
{
    [self setFillStyle:color];
    [self fillPath:points];
}

-(void) drawRectWithX1:(CGFloat) x1 withY1:(CGFloat) y1 withX2:(CGFloat) x2 withY2:(CGFloat) y2 withLineWidth:(CGFloat) lineWidth withLineColor:(NSString *) color
{
    [self setLineWidth:lineWidth];
    [self setStrokeStyle:color];
    CGContextBeginPath(self.context);
    CGContextMoveToPoint(self.context, x1, y1);
    CGContextAddLineToPoint(self.context, x1, y2);
    CGContextAddLineToPoint(self.context, x2, y2);
    CGContextAddLineToPoint(self.context, x2, y1);
    CGContextAddLineToPoint(self.context, x1, y1);
    CGContextDrawPath(self.context, kCGPathStroke);
}

-(void) storkeRectLeftBottomWithX:(CGFloat) x withY:(CGFloat) y withWidth:(CGFloat) width withHeight:(CGFloat) height
{
    [self storkeRect:CGRectMake(x, y-height, width, height)];
}
-(void) storkeRectLeftBottom:(CGRect) rect
{
    [self storkeRectLeftBottomWithX:rect.origin.x withY:rect.origin.y withWidth:rect.size.width withHeight:rect.size.height];
}
-(void) storkeRectLeftBottomWithX:(CGFloat) x withY:(CGFloat) y withWidth:(CGFloat) width withHeight:(CGFloat) height withStrokeColor: (NSString *) color
{
    [self setStrokeStyle:color];
    [self storkeRectLeftBottomWithX: x withY: y withWidth: width withHeight: height];
}
-(void) storkeRectLeftBottom:(CGRect) rect withStrokeColor: (NSString *) color
{
    [self storkeRectLeftBottomWithX:rect.origin.x withY:rect.origin.y withWidth:rect.size.width withHeight:rect.size.height withStrokeColor:color];
}

-(void) fillRectLeftBottomWithX:(CGFloat) x withY:(CGFloat) y withWidth:(CGFloat) width withHeight:(CGFloat) height
{
    [self fillRectWithX:x withY:y-height withWidth:width withHeight:height];
}
-(void) fillRectLeftBottom:(CGRect) rect
{
    [self fillRectLeftBottomWithX:rect.origin.x withY:rect.origin.y withWidth:rect.size.width withHeight:rect.size.height];
}
-(void) fillRectLeftBottomWithX:(CGFloat) x withY:(CGFloat) y withWidth:(CGFloat) width withHeight:(CGFloat) height withFillColor:(NSString *) color
{
    [self setFillStyle:color];
    [self fillRectLeftBottomWithX:x withY:y withWidth:width withHeight:height];
}

-(void) fillRectLeftBottomWithX:(CGFloat) x withY:(CGFloat) y withWidth:(CGFloat) width withHeight:(CGFloat) height withFillUIColor:(UIColor *) color
{
    [self setFillColor:color];
    [self fillRectLeftBottomWithX:x withY:y withWidth:width withHeight:height];
}

-(void) fillRectLeftBottom:(CGRect) rect withFillColor:(NSString *) color
{
    [self setFillStyle:color];
    [self fillRectLeftBottom:rect];
}

-(void) fillCircleWithX:(CGFloat) x withY:(CGFloat) y withRadius:(CGFloat) radius
{
    CGContextAddArc(self.context, x, y, radius, 0, 2 * (float)M_PI, 0);
    CGContextFillPath(self.context);
}
-(void) fillCircleWithX:(CGFloat) x withY:(CGFloat) y withRadius:(CGFloat) radius withFillColor:(NSString *) color
{
    [self setFillStyle:color];
    [self fillCircleWithX:x withY:y withRadius:radius];
}

-(void) storkeCircleWithX:(CGFloat) x withY:(CGFloat) y withRadius:(CGFloat) radius
{
    CGContextAddArc(self.context, x, y, radius, 0, 2 * (float)M_PI, 0);
    CGContextStrokePath(self.context);
}
-(void) storkeCircleWithX:(CGFloat) x withY:(CGFloat) y withRadius:(CGFloat) radius withFillColor:(NSString *) color
{
    [self setStrokeStyle:color];
    [self storkeCircleWithX:x withY:y withRadius:radius];
}

-(void) fillDonutWithX:(CGFloat) x withY:(CGFloat) y withInnerRadius:(CGFloat) innerRadius withOuterRadius:(CGFloat) outerRadius
{
    CGContextAddArc(self.context, x, y, innerRadius, 0, 2 * (float)M_PI, 0);
    CGContextAddArc(self.context, x, y, outerRadius, 0, 2 * (float)M_PI, 0);
    CGContextEOFillPath(self.context);
}

-(void) fillDonutWithX:(CGFloat) x withY:(CGFloat) y withInnerRadius:(CGFloat) innerRadius withOuterRadius:(CGFloat) outerRadius withFillColor:(NSString *) color
{
    [self setFillStyle:color];
    [self fillDonutWithX:x withY:y withInnerRadius:innerRadius withOuterRadius:outerRadius];
}

-(CGRect) getTextRect:(NSString *) text withFont:(NSString *) font withSize:(CGFloat) size
{
    NSMutableAttributedString* attString = [[NSMutableAttributedString alloc]
                                            initWithString:text];
    
    [attString addAttribute:NSFontAttributeName
                      value:[UIFont fontWithName:font size:size]
                      range:NSMakeRange(0, [attString length])];
    
    return [attString boundingRectWithSize:CGSizeMake(10000, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];
}

-(CGRect) fillText:(NSString *) text withX:(CGFloat) x withY:(CGFloat) y withColor:(NSString *) color withFont:(NSString *) font withSize:(CGFloat) size
{
   return [self fillText:text withX:x withY:y withColor:color withFont:font withSize:size withAnchor:LeftTop];
}

-(CGRect) fillText:(NSString *) text withX:(CGFloat) x withY:(CGFloat) y withColor:(NSString *) color withFont:(NSString *) font withSize:(CGFloat) size withAnchor:(ChartCanvasTextAnchor) anchor
{
    if ([text isEqualToString:@""]) {
        return CGRectZero;
    }
    NSMutableAttributedString* attString = [[NSMutableAttributedString alloc]
                                      initWithString:text];

    [attString addAttribute:NSFontAttributeName
                      value:[UIFont fontWithName:font size:size]
                      range:NSMakeRange(0, [attString length])];

    [attString addAttribute:NSForegroundColorAttributeName value:[ChartCanvas colorWithHexString: color] range:NSMakeRange(0, [attString length])];

    CGRect rect = [attString boundingRectWithSize:CGSizeMake(10000, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];

    switch (anchor) {
        case CenterMiddle:
            y -= rect.size.height/2;
            x -= rect.size.width/2;
            break;
        case CenterTop:
            x -= rect.size.width/2;
            break;
        case CenterBottom:
            x -= rect.size.width/2;
            y -= rect.size.height;
            break;
        case RightBottom:
            y -= rect.size.height;
            x -= rect.size.width;
            break;
        case RightMiddle:
            y -= rect.size.height/2;
            x -= rect.size.width;
            break;
        case RightTop:
            x -= rect.size.width;
            break;
        case LeftBottom:
            y -= rect.size.height;
            break;
        case LeftMiddle:
            y -= rect.size.height/2;
            break;
        case LeftTop:
            break;
    }

    rect.origin.x = x;
    rect.origin.y = y;



    [attString drawAtPoint:CGPointMake(x, y)];

    return rect;
}

- (CGRect)fillAttributedString:(NSAttributedString *)attributedString atPoint:(CGPoint)point anchor:(ChartCanvasTextAnchor)anchor
{
    CGRect rect = [attributedString boundingRectWithSize:CGSizeMake(10000, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];
    CGPoint pt = [self adjustPoint:point basedOn:rect.size anchor:anchor];
    rect.origin = pt;
    [attributedString drawAtPoint:pt];
    return rect;
}

- (CGPoint)adjustPoint:(CGPoint)point basedOn:(CGSize)size anchor:(ChartCanvasTextAnchor)anchor
{
    switch (anchor) {
        case CenterMiddle:
            point.y -= size.height/2;
            point.x -= size.width/2;
            break;
        case CenterTop:
            point.x -= size.width/2;
            break;
        case CenterBottom:
            point.x -= size.width/2;
            point.y -= size.height;
            break;
        case RightBottom:
            point.y -= size.height;
            point.x -= size.width;
            break;
        case RightMiddle:
            point.y -= size.height/2;
            point.x -= size.width;
            break;
        case RightTop:
            point.x -= size.width;
            break;
        case LeftBottom:
            point.y -= size.height;
            break;
        case LeftMiddle:
            point.y -= size.height/2;
            break;
        case LeftTop:
            break;
    }
    return point;
}

-(CGRect) fillTexts:(NSArray *) texts withX:(CGFloat) x withY:(CGFloat) y withColors:(NSArray *) colors withFonts:(NSArray *) fonts withSizes:(NSArray*) sizes withAnchor:(ChartCanvasTextAnchor) anchor
{
    NSString * text = @"";
    
    for (NSString * str in texts) {
       text = [text stringByAppendingString:str];
    }
    
    NSMutableAttributedString* attString = [[NSMutableAttributedString alloc]
                                            initWithString:text];
    size_t count = 0;
    size_t textLength;
    for (NSUInteger i = 0;i < fonts.count; i++) {
        textLength = [texts[i] length];
        NSRange range = NSMakeRange(count, textLength);
        
        [attString addAttribute:NSFontAttributeName
                          value:[UIFont fontWithName: fonts[i] size:[sizes[i] floatValue]]
                          range:range];
        
        [attString addAttribute:NSForegroundColorAttributeName value:[ChartCanvas colorWithHexString: colors[i] ] range:range];
        
        count += textLength;
        
    }
    
    CGRect rect = [attString boundingRectWithSize:CGSizeMake(10000, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil];
    
    switch (anchor) {
        case CenterMiddle:
            y -= rect.size.height/2;
            x -= rect.size.width/2;
            break;
        case CenterTop:
            x -= rect.size.width/2;
            break;
        case CenterBottom:
            x -= rect.size.width/2;
            y -= rect.size.height;
            break;
        case RightBottom:
            y -= rect.size.height;
            x -= rect.size.width;
            break;
        case RightMiddle:
            y -= rect.size.height/2;
            x -= rect.size.width;
            break;
        case RightTop:
            x -= rect.size.width;
            break;
        case LeftBottom:
            y -= rect.size.height;
            break;
        case LeftMiddle:
            y -= rect.size.height/2;
            break;
        case LeftTop:
            break;
    }
    
    rect.origin.x = x;
    rect.origin.y = y;
    
    [attString drawAtPoint:CGPointMake(x, y)];
    
    return rect;
}

-(void) clipToRect:(CGRect) rect
{
    CGContextClipToRect(self.context, rect);
}


// 都是255
+ (CGFloat) colorComponentFrom: (NSString *) string start: (NSUInteger) start length: (NSUInteger) length {
    NSString *substring = [string substringWithRange: NSMakeRange(start, length)];
    NSString *fullHex = length == 2 ? substring : [NSString stringWithFormat: @"%@%@", substring, substring];
    unsigned hexComponent;
    [[NSScanner scannerWithString: fullHex] scanHexInt: &hexComponent];
    return hexComponent / 255.0;
}

+ (UIColor *) colorWithHexString: (NSString *) hexString {
    NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];
    CGFloat alpha, red, blue, green;
    switch ([colorString length]) {
        case 3: // #RGB
            alpha = 1.0f;
            red   = [self colorComponentFrom: colorString start: 0 length: 1];
            green = [self colorComponentFrom: colorString start: 1 length: 1];
            blue  = [self colorComponentFrom: colorString start: 2 length: 1];
            break;
        case 4: // #ARGB
            alpha = [self colorComponentFrom: colorString start: 0 length: 1];
            red   = [self colorComponentFrom: colorString start: 1 length: 1];
            green = [self colorComponentFrom: colorString start: 2 length: 1];
            blue  = [self colorComponentFrom: colorString start: 3 length: 1];
            break;
        case 6: // #RRGGBB
            alpha = 1.0f;
            red   = [self colorComponentFrom: colorString start: 0 length: 2];
            green = [self colorComponentFrom: colorString start: 2 length: 2];
            blue  = [self colorComponentFrom: colorString start: 4 length: 2];
            break;
        case 8: // #AARRGGBB
            alpha = [self colorComponentFrom: colorString start: 0 length: 2];
            red   = [self colorComponentFrom: colorString start: 2 length: 2];
            green = [self colorComponentFrom: colorString start: 4 length: 2];
            blue  = [self colorComponentFrom: colorString start: 6 length: 2];
            break;
        default:
            [NSException raise:@"Invalid color value" format: @"Color value %@ is invalid.  It should be a hex value of the form #RBG, #ARGB, #RRGGBB, or #AARRGGBB", hexString];
            break;
    }
    return [UIColor colorWithRed: red green: green blue: blue alpha: alpha];
}

+ (NSArray *) colorsWithHexString: (NSString *) hexString count:(NSInteger )count sortDir:(NSInteger)sortDir{
    if (count <= 0) {
        [NSException raise:@"Invalid count value" format: @"count value %@ is invalid.  It should be 1 or -1", count];
    }
    NSString *colorString = [[hexString stringByReplacingOccurrencesOfString: @"#" withString: @""] uppercaseString];
    CGFloat alpha, red, blue, green;
    switch ([colorString length]) {
        case 3: // #RGB
            alpha = 1.0f;
            red   = [self colorComponentFrom: colorString start: 0 length: 1];
            green = [self colorComponentFrom: colorString start: 1 length: 1];
            blue  = [self colorComponentFrom: colorString start: 2 length: 1];
            break;
        case 4: // #ARGB
            alpha = [self colorComponentFrom: colorString start: 0 length: 1];
            red   = [self colorComponentFrom: colorString start: 1 length: 1];
            green = [self colorComponentFrom: colorString start: 2 length: 1];
            blue  = [self colorComponentFrom: colorString start: 3 length: 1];
            break;
        case 6: // #RRGGBB
            alpha = 1.0f;
            red   = [self colorComponentFrom: colorString start: 0 length: 2];
            green = [self colorComponentFrom: colorString start: 2 length: 2];
            blue  = [self colorComponentFrom: colorString start: 4 length: 2];
            break;
        case 8: // #AARRGGBB
            alpha = [self colorComponentFrom: colorString start: 0 length: 2];
            red   = [self colorComponentFrom: colorString start: 2 length: 2];
            green = [self colorComponentFrom: colorString start: 4 length: 2];
            blue  = [self colorComponentFrom: colorString start: 6 length: 2];
            break;
        default:
            [NSException raise:@"Invalid color value" format: @"Color value %@ is invalid.  It should be a hex value of the form #RBG, #ARGB, #RRGGBB, or #AARRGGBB", hexString];
            break;
    }
    CGFloat tmp = alpha / count;
    NSMutableArray *array = [NSMutableArray array];
    
    for (NSInteger i = 1; i <= count; i++) {
        
        if (sortDir == 1) {
            alpha = (alpha - tmp * i);
        }
        else if (sortDir == -1) {
            alpha = tmp * i;
        }
        [array addObject:[UIColor colorWithRed: red green: green blue: blue alpha: alpha]];
    }
    return array.copy;
}

- (void) fillHJJTTexts:(NSString *)text withCGRect:(CGRect)rect withColor:(NSString *)color withFontName:(NSString *)font withSize:(NSString *)size withAnchor:(ChartCanvasTextAnchor) anchor//描绘文字
{
//    NSMutableAttributedString *attString = [[NSMutableAttributedString alloc]
//                                            initWithString:text];
//    
//    [attString addAttributes:@{NSForegroundColorAttributeName:[ChartCanvas colorWithHexString:color],
//                               NSFontAttributeName:[UIFont fontWithName:font size:[size floatValue]]}
//                       range:NSMakeRange(0, [attString length])];
    
//    CGSize strSize = [attString boundingRectWithSize:CGSizeMake(10000, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading context:nil].size;
    CGRect strSize = [text boundingRectWithSize:CGSizeMake(10000, 10000) options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading attributes:@{NSFontAttributeName:[UIFont systemFontOfSize:[size floatValue]]} context:nil];
    CGFloat y = 0, height = strSize.size.height;
    
    switch (anchor) {
        case CenterTop:
            y = 6;
            break;
        case CenterMiddle:
            y = (rect.size.height - height)/2;
            break;
        case CenterBottom:
            y = rect.size.height - height-6;
            break;
        case RightBottom://to fulfill the function.
            break;
        case RightMiddle://to fulfill the function.
            break;
        case RightTop://to fulfill the function.
            break;
        case LeftBottom://to fulfill the function.
            break;
        case LeftMiddle://to fulfill the function.
            break;
        case LeftTop://to fulfill the function.
            break;
    }
    
    if (rect.size.height - height <= 0)
        return;//不展示目前数据库中的异常数据
    else
        y += rect.origin.y;
    
    NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init];
    paragraphStyle.alignment = NSTextAlignmentCenter;
    
    [text drawInRect:(CGRect){rect.origin.x, y, rect.size.width, height}
      withAttributes:@{NSParagraphStyleAttributeName:paragraphStyle,
                       NSForegroundColorAttributeName:[ChartCanvas colorWithHexString:color],
                       NSFontAttributeName:[UIFont fontWithName:font size:[size floatValue]]}];
}

- (void)drawLinearGradientInRect:(CGRect)pathRect direction:(LinearGradientDirection)direction startColor:(NSString *)startColor endColor:(NSString *)endColor {//横向或纵向 线性渐进图
    CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB();
    NSArray* gradientColors = [NSArray arrayWithObjects:
                               (id)[ChartCanvas colorWithHexString:startColor].CGColor,
                               (id)[ChartCanvas colorWithHexString:endColor].CGColor, nil];
    const size_t locationCount = 2;
    CGFloat locations[locationCount] = {0.0, 1.0};
    CGGradientRef gradient = CGGradientCreateWithColors(colorspace,
                                                        (__bridge CFArrayRef)gradientColors,
                                                        locations);
    
    CGPoint startPoint = CGPointZero, endPoint = CGPointZero;
    if (direction == LinearGradientFromLeftToRight) {
        startPoint = CGPointMake(CGRectGetMinX(pathRect), CGRectGetMinY(pathRect));
        endPoint = CGPointMake(CGRectGetMaxX(pathRect), CGRectGetMinY(pathRect));
    } else if (direction == LinearGradientFromBottomToUp) {
        startPoint = CGPointMake(CGRectGetMinX(pathRect), CGRectGetMinY(pathRect));
        endPoint = CGPointMake(CGRectGetMinX(pathRect), CGRectGetMaxY(pathRect));
    } else if (direction == LinearGradientFromRightToLeft) {
        startPoint = CGPointMake(CGRectGetMinX(pathRect), CGRectGetMaxY(pathRect));
        endPoint = CGPointMake(CGRectGetMinX(pathRect), CGRectGetMinY(pathRect));
    } else if (direction == LinearGradientFromUpToBottom) {
        startPoint = CGPointMake(CGRectGetMinX(pathRect), CGRectGetMaxY(pathRect));
        endPoint = CGPointMake(CGRectGetMinX(pathRect), CGRectGetMinY(pathRect));
    }
    
    UIBezierPath *path = [UIBezierPath bezierPathWithRect:pathRect];
    [path closePath];
    
    CGContextSaveGState(self.context);
    CGContextAddPath(self.context, path.CGPath);
    CGContextClip(self.context);
    CGContextDrawLinearGradient(self.context, gradient, startPoint, endPoint, locationCount);
    CGContextRestoreGState(self.context);
    
    CGColorSpaceRelease(colorspace);
    CGGradientRelease(gradient);
}



@end
